/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package edu.yonsei.iwb.smarttv.gui;


import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.*;
import java.io.File;
import java.util.Hashtable;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
import javax.swing.GroupLayout.Group;
import javax.swing.GroupLayout.ParallelGroup;
import javax.swing.GroupLayout.SequentialGroup;
import javax.swing.JPopupMenu.Separator;
import javax.swing.border.TitledBorder;
import javax.swing.table.DefaultTableModel;
import kr.ac.kaist.swrc.jhannanum.comm.Eojeol;

/**
 *
 * @author Soo
 */
public class MainFrame extends JFrame implements ActionListener{
    private JMenuItem selectOntFileMenuItem;//jMenuItem1
    private JMenuItem exitMenuItem;//jMenuItem2
    private Separator jSeparator1;//jSeparator1
    private Separator jSeparator2;//jSeparator2
    private JMenuBar menuBar;//jMenuBar1
    private JMenu fileMenu;//jMenu2
    private JMenu loadOntMenu;//jMenu3
    private JMenu ontTDBMenu;//jMenu4
    private JMenu loadIndexMenu;//jMenu5
    private JMenu indexUseFileMenu;//jMenu6
    private JMenuItem ontUseMemoryMenuItem;//jMenuItem3
    private JMenuItem ontTDBNewMenuItem;//jMenuItem4
    private JMenuItem ontTDBOpenMenuItem;//jMenuItem5
    private JMenuItem indexUseMemoryMenuItem;//jMenuItem6
    private JMenuItem indexUseFileNewMenuItem;//jMenuItem7
    private JMenuItem indexUseFileOpenMenuItem;//jMenuItem8
    private JButton runButton; //jButton1;
    private JButton continueButton; //jButton2;
    private JButton nextButton; //jButton3;
    private JButton backButton; //jButton4;
    private JLabel userQueryLabel; //jLabel1
    private JPanel userQueryPanel;//jPanel1
    private JPanel maPanel;//jPanel2
    private JPanel nerPanel;//jPanel3
    private JPanel buttonPanel;
    private JPanel graphViewPanel;
    private JPanel graphPanel;//jPanel4
    private JPanel conceptualGraphPanel;
    private JPanel spanningTreePanel;
    private JPanel shortestPathPanel;
    private JPanel sparqlPanel;
    private JPanel searchResultPanel;
    private JScrollPane outputScrollPane;//jScrollPane1
    private JScrollPane maScrollPane;//jScrollPane2
    private JScrollPane nerScrollPane;//jScrollPane3
    private JScrollPane searchResultScrollPane;//jScrollPane4
    private JScrollPane graphViewScrollPane;
    private JSplitPane queryAndOtherSplitPane;//jSplitPane1
    private JSplitPane outputAndOtherSplitPane;//jSplitPane2
    private JSplitPane graphAndOtherSplitPane;//jSplitPane3
    private JSplitPane maAndNerSplitPane;//jSplitPane4
    private JTable maTable;//jTable1
    private JTable nerTable;//jTable2
    private JTable searchResultTable;//jTable3
    private JTextField userQueryTextField;//jTextField1
    private JTextArea outputTextArea;//jTextArea1
    private DefaultTableModel maTableModel;
    private DefaultTableModel nerTableModel;
    private DefaultTableModel searchResultModel;
    private GroupLayout graphViewPanelLayout;
    Hashtable<ButtonModel, String> hm;
//    Hashtable<JRadioButton, String> hm;
    ButtonGroup bg;
    
    private String ontology;
//    private String checkOntMenuItem;
//    private String checkIndexMenuItem;
    private boolean checkRunButton;
    private boolean checkOntSelected;
    private boolean checkOntLoaded;
    private boolean checkIndexLoaded;
    private Controller controller;
    private int checkCurrentGraphPanel;
    private boolean isFirstTime;


    

    public MainFrame() {

        controller = new Controller();
        checkRunButton = false;
        checkOntSelected = false;
        checkIndexLoaded = false;
        checkOntLoaded = false;
        queryAndOtherSplitPane = new JSplitPane();
        userQueryPanel = new JPanel();
        userQueryLabel = new JLabel();
        userQueryTextField = new JTextField();
        runButton = new JButton();
        outputAndOtherSplitPane = new JSplitPane();
        graphAndOtherSplitPane = new JSplitPane();
        maAndNerSplitPane = new JSplitPane();
        maPanel = new JPanel();
        maScrollPane = new JScrollPane();
        maTable = new JTable();
        nerPanel = new JPanel();
        nerScrollPane = new JScrollPane();
        nerTable = new JTable();
        searchResultTable = new JTable();
        continueButton = new JButton();
        graphPanel = new JPanel();
        outputScrollPane = new JScrollPane();
        outputTextArea = new JTextArea();
        menuBar = new JMenuBar();
        fileMenu = new JMenu();
        loadOntMenu = new JMenu();
        ontUseMemoryMenuItem = new JMenuItem();
        ontTDBMenu = new JMenu();
        ontTDBNewMenuItem = new JMenuItem();
        ontTDBOpenMenuItem = new JMenuItem();
        loadIndexMenu = new JMenu();
        indexUseFileMenu = new JMenu();
        indexUseFileNewMenuItem = new JMenuItem();
        indexUseFileOpenMenuItem = new JMenuItem();
        indexUseMemoryMenuItem = new JMenuItem();
        maTableModel = new DefaultTableModel();
        nerTableModel = new DefaultTableModel();
        searchResultModel = new DefaultTableModel();
        selectOntFileMenuItem = new JMenuItem();
        exitMenuItem = new JMenuItem();
        jSeparator1 = new Separator();
        jSeparator2 = new Separator();
        nextButton = new JButton();
        backButton = new JButton();
        checkCurrentGraphPanel = CurrentGraphPanelInfo.NONE;
        buttonPanel = new JPanel();
        graphViewScrollPane = new JScrollPane();
//        hm = new Hashtable<ButtonModel, String>();
//        bg = new ButtonGroup(); 

        //main frame
        setTitle("SmartTV Search System");
//        setVisible(true);
//        setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
//        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        ImageIcon image = new ImageIcon("resources/SmartTV_icon.jpg");
        this.setIconImage(image.getImage());
        this.setPreferredSize(new Dimension(800, 800));

        
        //Menubar
        setJMenuBar(menuBar);             
        menuBar.add(fileMenu);
        fileMenu.setText("File");
        fileMenu.add(selectOntFileMenuItem);        
        selectOntFileMenuItem.setText("Select Ontology File...");
        fileMenu.add(jSeparator1); 
        fileMenu.add(loadOntMenu);
        fileMenu.add(loadIndexMenu);
        fileMenu.add(jSeparator2);
        fileMenu.add(exitMenuItem);        
        exitMenuItem.setText("Exit");
        
        loadOntMenu.setText("Load Ontology...");
        loadOntMenu.add(ontUseMemoryMenuItem);
        loadOntMenu.add(ontTDBMenu);
        ontUseMemoryMenuItem.setText("Use Memory...");        
        ontTDBMenu.setText("Use TDB...");
        ontTDBMenu.add(ontTDBNewMenuItem);
        ontTDBMenu.add(ontTDBOpenMenuItem);
        ontTDBNewMenuItem.setText("New...");
        ontTDBOpenMenuItem.setText("Open...");
        
        selectOntFileMenuItem.addActionListener(this);
        ontUseMemoryMenuItem.addActionListener(this);        
        ontTDBNewMenuItem.addActionListener(this);
        ontTDBOpenMenuItem.addActionListener(this);
                
        loadIndexMenu.setText("Load Index...");
        loadIndexMenu.add(indexUseFileMenu);
        loadIndexMenu.add(indexUseMemoryMenuItem);        
        indexUseFileMenu.setText("Use File Index...");
        indexUseFileMenu.add(indexUseFileNewMenuItem);
        indexUseFileMenu.add(indexUseFileOpenMenuItem);        
        indexUseMemoryMenuItem.setText("Use Memory Index...");
        indexUseFileNewMenuItem.setText("New...");
        indexUseFileOpenMenuItem.setText("Open...");

        indexUseFileNewMenuItem.addActionListener(this);
        indexUseFileOpenMenuItem.addActionListener(this);
        indexUseMemoryMenuItem.addActionListener(this);
        exitMenuItem.addActionListener(this);
        
        queryAndOtherSplitPane.setBorder(null);
        queryAndOtherSplitPane.setDividerLocation(50);
        queryAndOtherSplitPane.setDividerSize(0);
        queryAndOtherSplitPane.setOrientation(JSplitPane.VERTICAL_SPLIT);
        
        userQueryPanel.setBorder(BorderFactory.createEtchedBorder());
        userQueryPanel.setPreferredSize(getMaximumSize());
        
        userQueryLabel.setFont(new java.awt.Font("맑은 고딕", 1, 12)); 
        userQueryLabel.setText("User Query : ");
        
        userQueryTextField.addKeyListener(new KeyAdapter(){
            public void keyTyped(KeyEvent e){
                if(e.getKeyChar() == KeyEvent.VK_ENTER){
                    runButton.doClick();
                }
            }
        });
                
        runButton.setText("Run");
        runButton.addActionListener(this);

        GroupLayout userQueryPanelLayout = new GroupLayout(userQueryPanel);
        userQueryPanel.setLayout(userQueryPanelLayout);
        userQueryPanelLayout.setHorizontalGroup(
            userQueryPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addGroup(userQueryPanelLayout.createSequentialGroup()
                .addGap(35, 35, 35)
                .addComponent(userQueryLabel)
                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(userQueryTextField, GroupLayout.DEFAULT_SIZE, 580, Short.MAX_VALUE)
                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(runButton)
                .addGap(35, 35, 35))
        );
        userQueryPanelLayout.setVerticalGroup(
            userQueryPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addGroup(userQueryPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(userQueryPanelLayout.createParallelGroup(GroupLayout.Alignment.CENTER)
                    .addComponent(runButton)
                    .addComponent(userQueryTextField, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                    .addComponent(userQueryLabel))
                .addContainerGap(10, Short.MAX_VALUE))
        );

        queryAndOtherSplitPane.setTopComponent(userQueryPanel);
        queryAndOtherSplitPane.setBottomComponent(outputAndOtherSplitPane);//setRightComponent
        outputAndOtherSplitPane.setTopComponent(graphAndOtherSplitPane);
        outputAndOtherSplitPane.setRightComponent(outputScrollPane);
        
        graphAndOtherSplitPane.setTopComponent(maAndNerSplitPane);
        graphAndOtherSplitPane.setRightComponent(graphPanel);
        maAndNerSplitPane.setLeftComponent(maPanel);
        maAndNerSplitPane.setRightComponent(nerPanel);
        
        outputAndOtherSplitPane.setDividerLocation(450);
        outputAndOtherSplitPane.setDividerSize(7);
        outputAndOtherSplitPane.setOrientation(JSplitPane.VERTICAL_SPLIT);
        outputAndOtherSplitPane.setOneTouchExpandable(true);

        graphAndOtherSplitPane.setDividerLocation(150);
        graphAndOtherSplitPane.setDividerSize(7);
        graphAndOtherSplitPane.setOrientation(JSplitPane.VERTICAL_SPLIT);
        graphAndOtherSplitPane.setOneTouchExpandable(true);

        maAndNerSplitPane.setDividerLocation(250);
        maAndNerSplitPane.setDividerSize(7);
        maAndNerSplitPane.setOneTouchExpandable(true);
        
        //maPanel
        maPanel.setBorder(BorderFactory.createTitledBorder(null, "형태소 분석", TitledBorder.CENTER, TitledBorder.DEFAULT_POSITION, new Font("맑은 고딕", 1, 12))); 
        maTable.setModel(setMATable());
        maScrollPane.setViewportView(maTable);

        GroupLayout maPanelLayout = new GroupLayout(maPanel);
        maPanel.setLayout(maPanelLayout);
        maPanelLayout.setHorizontalGroup(
            maPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addGroup(maPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(maScrollPane, GroupLayout.DEFAULT_SIZE, 213, Short.MAX_VALUE)
                .addContainerGap())
        );
        maPanelLayout.setVerticalGroup(
            maPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addComponent(maScrollPane, GroupLayout.DEFAULT_SIZE, 67, Short.MAX_VALUE)
        );
        
        //nerPanel
        nerPanel.setBorder(BorderFactory.createTitledBorder(null, "개체 식별 결과", TitledBorder.CENTER, TitledBorder.DEFAULT_POSITION, new Font("맑은 고딕", 1, 12))); 
        nerTable.setModel(setNERTable());
        nerScrollPane.setViewportView(nerTable);

        continueButton.setText("Continue");
        continueButton.addActionListener(this);

        GroupLayout nerPanelLayout = new GroupLayout(nerPanel);
        nerPanel.setLayout(nerPanelLayout);
        nerPanelLayout.setHorizontalGroup(
            nerPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addGroup(nerPanelLayout.createSequentialGroup()
                .addComponent(nerScrollPane, GroupLayout.DEFAULT_SIZE, 460, Short.MAX_VALUE)
                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(continueButton))
        );
        nerPanelLayout.setVerticalGroup(
            nerPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addGroup(nerPanelLayout.createSequentialGroup()
                .addGap(0, 44, Short.MAX_VALUE)
                .addComponent(continueButton))
            .addComponent(nerScrollPane, GroupLayout.Alignment.TRAILING, GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
        );
        
        //searchResultPanel
        searchResultTable.setModel(setSearchResultTable());
        

        nextButton.setText("Next");
        backButton.setText("Back");
        nextButton.addActionListener(this);
        backButton.addActionListener(this);
        
        graphViewScrollPane.setBorder(null);
        
        //next and back button panel layout
        GroupLayout buttonPanelLayout = new GroupLayout(buttonPanel);
        buttonPanel.setLayout(buttonPanelLayout);
        buttonPanelLayout.setHorizontalGroup(
            buttonPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addGroup(buttonPanelLayout.createSequentialGroup()
                .addComponent(backButton)
                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addComponent(nextButton))
        );
        buttonPanelLayout.setVerticalGroup(
            buttonPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addGroup(GroupLayout.Alignment.TRAILING, buttonPanelLayout.createSequentialGroup()
                .addGap(10, 10, 10)
                .addGroup(buttonPanelLayout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                    .addComponent(backButton)
                    .addComponent(nextButton))
                .addContainerGap())
        );

        outputTextArea.setColumns(20);
        outputTextArea.setRows(5);
        outputScrollPane.setViewportView(outputTextArea);
        
        //total frame layout
        GroupLayout layout = new GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addComponent(queryAndOtherSplitPane)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addComponent(queryAndOtherSplitPane, GroupLayout.DEFAULT_SIZE, 579, Short.MAX_VALUE)
        );
        
        pack();
        
    }
    
    public DefaultTableModel setMATable() {
        maTableModel.setColumnIdentifiers(new String[]{"어절", "태그"});
        return maTableModel;
    }
        
    public DefaultTableModel setNERTable() {
        nerTableModel.setColumnIdentifiers(new String[]{"키워드", "Node URI", "Node Label", "Type"});
        return nerTableModel;
    }    
    
    public DefaultTableModel setSearchResultTable() {
        searchResultModel.setColumnIdentifiers(new String[]{"No.", "Media", "Type"});
        return searchResultModel;
    }    
    
    public boolean isOntologyLoaded(){
        return this.checkOntLoaded;
    }
    
    public String getOntology(){
        return this.ontology;
    }
    

    @Override
    public void actionPerformed(ActionEvent ae) {
        Object o = ae.getSource();
        File file;
        JFileChooser  ontFileChooser;
        if(o == exitMenuItem){
            this.dispose();
        }else if(o == selectOntFileMenuItem){
            ontFileChooser = new JFileChooser("./");
            ontFileChooser.setFileSelectionMode(ontFileChooser.FILES_ONLY);
            ontFileChooser.setMultiSelectionEnabled(false);//다중 선택 불가
            int returnVal = ontFileChooser.showOpenDialog(this);

            if (returnVal == JFileChooser.APPROVE_OPTION){
                file = ontFileChooser.getSelectedFile();
                ontology = file.getPath();
                outputTextArea.append("Select Ontology File: "+file.getPath()+"\n");
                controller.selectOntFile(ontology);
                checkOntSelected = true;
            }else {
                outputTextArea.append("작업 취소"+"\n");
            }  
        }else if(o == ontTDBNewMenuItem | o == ontTDBOpenMenuItem | o == indexUseFileNewMenuItem | o == indexUseFileOpenMenuItem){
            ontFileChooser = new JFileChooser();
            ontFileChooser.setFileSelectionMode(ontFileChooser.DIRECTORIES_ONLY);
            int returnVal = ontFileChooser.showOpenDialog(this);
            if(o == ontTDBOpenMenuItem | o == indexUseFileOpenMenuItem){
                if (returnVal == JFileChooser.APPROVE_OPTION){
                    file = ontFileChooser.getSelectedFile();
                    if(o == ontTDBOpenMenuItem){
                        outputTextArea.append("Select Ontology TDB Directory: "+file.getPath()+"\n");
                        controller.useTDBModel(file.getPath());
                        checkOntLoaded = true;                        
                    }else{
                        outputTextArea.append("Select Index File Directory: "+file.getPath()+"\n");
                        controller.useFileIndex(file.getPath());
                        checkIndexLoaded = true;
                    }                    
                }else{
                    outputTextArea.append("작업 취소"+"\n");
                }    
            }else{
                if(checkOntSelected == true){
                    if (returnVal == JFileChooser.APPROVE_OPTION){
                            file = ontFileChooser.getSelectedFile();
                        if(o == ontTDBNewMenuItem){
                            outputTextArea.append("Select Directory To Generate TDB: " + file.getPath() + "\n");
                            controller.loadOntOnTDB(file.getPath());
                            checkOntLoaded = true;
                        }else if(o == indexUseFileNewMenuItem){
                            if(checkOntLoaded == true){
                                outputTextArea.append("Generate Index File In: " + file.getPath() + "\n");
                                controller.loadIndexInDir(file.getPath());
                                checkIndexLoaded = true;
                            }else{
                                JOptionPane.showMessageDialog(this, "Load Ontology First!!", "Error", JOptionPane.WARNING_MESSAGE);
                            }
                        }
                    }else{
                        outputTextArea.append("작업 취소"+"\n");
                    }
                }else{
                    JOptionPane.showMessageDialog(this, "Select Ontology File First!!", "Error", JOptionPane.WARNING_MESSAGE);
                }
            }
        }else if(o == ontUseMemoryMenuItem | o == indexUseMemoryMenuItem){
            if(o == ontUseMemoryMenuItem){
                if(checkOntSelected == true){
                    outputTextArea.append("Load Ontology In The Memory \n");
                    controller.loadOntOnMemory();
                    checkOntLoaded = true;
                }else{
                    JOptionPane.showMessageDialog(this, "Select Ontology File First!!", "Error", JOptionPane.WARNING_MESSAGE);
                }
            }else{
                if(checkOntLoaded == true){
                    outputTextArea.append("Generate Index In The Memory \n");
                    controller.loadIndexOnMemory();
                    checkIndexLoaded = true;
                }else{
                    JOptionPane.showMessageDialog(this, "Load Ontology File First!!", "Error", JOptionPane.WARNING_MESSAGE);
                }
            }
        }else if(o == runButton){
            isFirstTime = true;
            String s = userQueryTextField.getText();
            if(s.replaceAll(" ", "").isEmpty()){
                JOptionPane.showMessageDialog(this, "Insert User Query!!", "Error", JOptionPane.WARNING_MESSAGE); 
                userQueryTextField.setText("");
            }else if(checkOntLoaded == false ){
                JOptionPane.showMessageDialog(this, "Load Ontology First!!", "Error", JOptionPane.WARNING_MESSAGE); 
            }else if(checkIndexLoaded == false){
                JOptionPane.showMessageDialog(this, "Load Index First!!", "Error", JOptionPane.WARNING_MESSAGE); 
            }else{
                outputTextArea.append("User Query: "+s+"\n");
                while (maTableModel.getRowCount()>0){
                    maTableModel.removeRow(0);
                }
                while (nerTableModel.getRowCount()>0){
                    nerTableModel.removeRow(0);
                }                
                Vector<String[]> maResult = controller.getMAResult(s);
                for(int i = 0; i < maResult.size(); i ++){
                    maTableModel.addRow(new String[]{maResult.get(i)[0], maResult.get(i)[1]});
                }
                Vector<String[]> nerResult = controller.getNERResult();
                if(nerResult.isEmpty()){
                    continueButton.setEnabled(false);
                }else{
                    continueButton.setEnabled(true);
                    for(int i = 0; i < nerResult.size(); i ++){
                        nerTableModel.addRow(new String[]{nerResult.get(i)[0], nerResult.get(i)[1], nerResult.get(i)[2], nerResult.get(i)[3]});
                    }
                }
                checkRunButton = true;
            }
        }else if(o == continueButton){
            if(checkRunButton == true ){
                checkCurrentGraphPanel = CurrentGraphPanelInfo.NONE;
                getGraphPanel();
                backButton.setEnabled(false);
                nextButton.setEnabled(true);
                graphViewPanel = new JPanel();
                graphViewPanel.setBorder(BorderFactory.createTitledBorder(null, "Conceptual Graph", TitledBorder.CENTER, TitledBorder.DEFAULT_POSITION, new Font("맑은 고딕", 1, 12)));
                graphViewScrollPane.setViewportView(graphViewPanel);
                graphViewPanelLayout = new GroupLayout(graphViewPanel);
                graphViewPanel.setLayout(graphViewPanelLayout);
                
                Vector<JPanel> cgvs = controller.getConceptualGraphViewSet();
                if(!cgvs.isEmpty()){
                    ParallelGroup graphPanelHorizontalGroup = graphViewPanelLayout.createParallelGroup(GroupLayout.Alignment.TRAILING);
                    SequentialGroup graphPanelVerticalGroup = graphViewPanelLayout.createSequentialGroup();
                    int num = cgvs.size();
                    for(int i = 0; i < num; i++){
                        JPanel cgGroupPanel = new JPanel();
                        cgGroupPanel.setBackground(Color.WHITE);
                        JLabel graphID = new JLabel("ID: ");
                        JPanel cgp = cgvs.get(i);
                        GroupLayout cgpLayout = new GroupLayout(cgGroupPanel);
                        cgGroupPanel.setLayout(cgpLayout);
                        cgp.setBackground(Color.WHITE);
                        setEachGraphViewPanelLayout(cgpLayout, graphID, cgp);
                        graphPanelHorizontalGroup = graphPanelHorizontalGroup.addComponent(cgGroupPanel, GroupLayout.Alignment.LEADING,GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE,  Short.MAX_VALUE);
                        graphPanelVerticalGroup =  graphPanelVerticalGroup.addComponent(cgGroupPanel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE).addPreferredGap(LayoutStyle.ComponentPlacement.RELATED);
                    }                    
                    setGraphViewPanelLayout(graphPanelHorizontalGroup, graphPanelVerticalGroup);
                    checkCurrentGraphPanel = CurrentGraphPanelInfo.CONCEPTUAL_GRAPH;
                    conceptualGraphPanel = graphViewPanel;
                    outputTextArea.append(num + " Conceptual Graphs are generated\n");
                }else{
                    outputTextArea.append("Conceptual Graph is not exist\n");
                    checkCurrentGraphPanel = CurrentGraphPanelInfo.CONCEPTUAL_GRAPH;
                }
            }else{
                JOptionPane.showMessageDialog(this, " Excute 'Run' button first!!", "Error", JOptionPane.WARNING_MESSAGE);
            }
        }else if(o == nextButton){
            backButton.setEnabled(true);
            if(checkCurrentGraphPanel == CurrentGraphPanelInfo.CONCEPTUAL_GRAPH){
                graphViewPanel = new JPanel();
                graphViewPanel.setBorder(BorderFactory.createTitledBorder(null, "Spanning Tree", TitledBorder.CENTER, TitledBorder.DEFAULT_POSITION, new Font("맑은 고딕", 1, 12)));
                graphViewScrollPane.setViewportView(graphViewPanel);
                graphViewPanelLayout = new GroupLayout(graphViewPanel);
                graphViewPanel.setLayout(graphViewPanelLayout);
                Vector<JPanel> stvs = controller.getSpanningTreeViewSet();
                if(!stvs.isEmpty()){
                    ParallelGroup graphPanelHorizontalGroup = graphViewPanelLayout.createParallelGroup(GroupLayout.Alignment.TRAILING);
                    SequentialGroup graphPanelVerticalGroup = graphViewPanelLayout.createSequentialGroup();
                    int num = stvs.size();
                    for(int i = 0; i < stvs.size(); i++){
                        JPanel stGroupPanel = new JPanel();
                        stGroupPanel.setBackground(Color.WHITE);
                        JLabel graphID = new JLabel("ID: ");
                        graphID.setSize(15, 4);
                        JPanel stp = stvs.get(i);
                        GroupLayout cgpLayout = new GroupLayout(stGroupPanel);
                        stGroupPanel.setLayout(cgpLayout);
                        stp.setBackground(Color.WHITE);
                        setEachGraphViewPanelLayout(cgpLayout, graphID, stp);
                        graphPanelHorizontalGroup = graphPanelHorizontalGroup.addComponent(stGroupPanel, GroupLayout.Alignment.LEADING,GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE,  Short.MAX_VALUE);
                        graphPanelVerticalGroup =  graphPanelVerticalGroup.addComponent(stGroupPanel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE).addPreferredGap(LayoutStyle.ComponentPlacement.RELATED);
                    }
                    setGraphViewPanelLayout(graphPanelHorizontalGroup, graphPanelVerticalGroup);
                    checkCurrentGraphPanel = CurrentGraphPanelInfo.SPANNING_TREE;
                    spanningTreePanel = graphViewPanel;
                    outputTextArea.append(num + " Spannig trees are generated\n");
                } else {
                    outputTextArea.append("Spanning tree is not exist\n");
                    checkCurrentGraphPanel = CurrentGraphPanelInfo.SPANNING_TREE;
                }
            }else if(checkCurrentGraphPanel == CurrentGraphPanelInfo.SPANNING_TREE){
                graphViewPanel = new JPanel();
                graphViewPanel.setBorder(BorderFactory.createTitledBorder(null, "Shortest Path", TitledBorder.CENTER, TitledBorder.DEFAULT_POSITION, new Font("맑은 고딕", 1, 12)));
                graphViewScrollPane.setViewportView(graphViewPanel);
                graphViewPanelLayout = new GroupLayout(graphViewPanel);
                graphViewPanel.setLayout(graphViewPanelLayout);
                Vector<JPanel> spvs = controller.getShortestPathViewSet();
                if(!spvs.isEmpty()){
                    ParallelGroup graphPanelHorizontalGroup = graphViewPanelLayout.createParallelGroup(GroupLayout.Alignment.TRAILING);
                    SequentialGroup graphPanelVerticalGroup = graphViewPanelLayout.createSequentialGroup();
                    int num = spvs.size();
                    for(int i = 0; i < spvs.size(); i++){
                        JPanel spGroupPanel = new JPanel();
                        spGroupPanel.setBackground(Color.WHITE);
                        JLabel graphID = new JLabel("ID: ");
                        JLabel graphScore = new JLabel("Score: ");
                        graphID.setSize(15, 4);
                        graphScore.setSize(15, 4);
                        JPanel spp = spvs.get(i);
                        GroupLayout sppLayout = new GroupLayout(spGroupPanel);
                        spGroupPanel.setLayout(sppLayout);
                        spp.setBackground(Color.WHITE);
                        setEachGraphViewPanelLayout(sppLayout, graphID, graphScore, spp);  
                        graphPanelHorizontalGroup = graphPanelHorizontalGroup.addComponent(spGroupPanel, GroupLayout.Alignment.LEADING,GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE,  Short.MAX_VALUE);
                        graphPanelVerticalGroup =  graphPanelVerticalGroup.addComponent(spGroupPanel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE).addPreferredGap(LayoutStyle.ComponentPlacement.RELATED);
                    }
                    setGraphViewPanelLayout(graphPanelHorizontalGroup, graphPanelVerticalGroup);
                    checkCurrentGraphPanel = CurrentGraphPanelInfo.SHORTEST_PATH;
                    shortestPathPanel = graphViewPanel;
                    outputTextArea.append(num + " Shortest paths are generated\n");
                } else {
                    outputTextArea.append(" Shortest path is not exist\n");
                    checkCurrentGraphPanel = CurrentGraphPanelInfo.SHORTEST_PATH;
                }
            }else if(checkCurrentGraphPanel == CurrentGraphPanelInfo.SHORTEST_PATH){
                hm = new Hashtable<ButtonModel, String>();
                bg = new ButtonGroup(); 
                graphViewPanel = new JPanel();
                graphViewPanel.setBorder(BorderFactory.createTitledBorder(null, "SPARQL", TitledBorder.CENTER, TitledBorder.DEFAULT_POSITION, new Font("맑은 고딕", 1, 12)));
                graphViewScrollPane.setViewportView(graphViewPanel);
                graphViewPanelLayout = new GroupLayout(graphViewPanel);
                graphViewPanel.setLayout(graphViewPanelLayout);
                ParallelGroup graphPanelHorizontalGroup = graphViewPanelLayout.createParallelGroup(GroupLayout.Alignment.TRAILING);
                SequentialGroup graphPanelVerticalGroup = graphViewPanelLayout.createSequentialGroup();
                JTextArea sparqlTextArea;
                JScrollPane sparqlScrollPane;
                JPanel sparqlGroupPane;
                JRadioButton sparqlRadioButton;
                Vector<String> sparqlSet = controller.getSPARQLViewSet();
                for(int i = 0; i < sparqlSet.size(); i++){
                    sparqlTextArea = new JTextArea();
                    sparqlTextArea.setColumns(20);
                    sparqlTextArea.setRows(10);
                    sparqlTextArea.append(sparqlSet.get(i));
                    sparqlScrollPane = new JScrollPane();
                    sparqlScrollPane.setViewportView(sparqlTextArea);
                    sparqlGroupPane = new JPanel();
                    sparqlRadioButton = new JRadioButton();
                    bg.add(sparqlRadioButton);
                    hm.put(sparqlRadioButton.getModel(), sparqlSet.get(i));
                    //sparql그룹패널레이아웃 = 라디오버튼과 sparql패널 레이아웃
                    GroupLayout sparqlGroupPaneLayout = new GroupLayout(sparqlGroupPane);
                    sparqlGroupPane.setLayout(sparqlGroupPaneLayout);
                    setSPARQLGroupPanelLayout(sparqlGroupPaneLayout, sparqlScrollPane, sparqlRadioButton);
                    graphPanelHorizontalGroup = graphPanelHorizontalGroup.addComponent(sparqlGroupPane,GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE);
                    graphPanelVerticalGroup =  graphPanelVerticalGroup.addComponent(sparqlGroupPane, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE).addPreferredGap(LayoutStyle.ComponentPlacement.RELATED);
                }
                if(bg.getElements().hasMoreElements()){
                    bg.setSelected(bg.getElements().nextElement().getModel(), true);
                }
                //sparql그룹패널들간의 레이아웃
                setGraphViewPanelLayout(graphPanelHorizontalGroup, graphPanelVerticalGroup);
                checkCurrentGraphPanel = CurrentGraphPanelInfo.SPARQL;
                sparqlPanel = graphViewPanel;               
                outputTextArea.append("SPARQL is Generated!!\n");
            }else if(checkCurrentGraphPanel == CurrentGraphPanelInfo.SPARQL){                
                graphViewScrollPane.setViewportView(searchResultTable);
                while (searchResultModel.getRowCount()>0){
                    searchResultModel.removeRow(0);
                }
                ButtonModel selectedRadioButtonModel = bg.getSelection();
                String selectedSPARQL = hm.get(selectedRadioButtonModel);
                Vector<String[]> searchResult = controller.getSearchResultBySelectedQuery(selectedSPARQL);
                for(int i = 0; i < searchResult.size(); i ++){
                    searchResultModel.addRow(new String[]{searchResult.get(i)[0], searchResult.get(i)[1], searchResult.get(i)[2]});
                }
                checkCurrentGraphPanel = CurrentGraphPanelInfo.SEARCH_RESULT;
                outputTextArea.append(" Execute SPARQL to ARQ Engine\n");
                nextButton.setEnabled(false);
            }else{
            }
            
        }else if(o == backButton){
            if(checkCurrentGraphPanel == CurrentGraphPanelInfo.SPANNING_TREE){
                backButton.setEnabled(false);
                graphViewScrollPane.setViewportView(conceptualGraphPanel);
                checkCurrentGraphPanel = CurrentGraphPanelInfo.CONCEPTUAL_GRAPH;
                outputTextArea.append(" Spanning Tree panel to Conceptual Graph panel\n");
            }else if(checkCurrentGraphPanel == CurrentGraphPanelInfo.SHORTEST_PATH){
                graphViewScrollPane.setViewportView(spanningTreePanel);
                checkCurrentGraphPanel = CurrentGraphPanelInfo.SPANNING_TREE;
                outputTextArea.append(" Shortest Path panel to Spanning Tree Panel\n");
            }else if(checkCurrentGraphPanel == CurrentGraphPanelInfo.SPARQL){
                graphViewScrollPane.setViewportView(shortestPathPanel);
                checkCurrentGraphPanel = CurrentGraphPanelInfo.SHORTEST_PATH;
                outputTextArea.append("SPARQL panel to Shortest path panel\n");
            }else if(checkCurrentGraphPanel == CurrentGraphPanelInfo.SEARCH_RESULT){
                nextButton.setEnabled(true);
                graphViewScrollPane.setViewportView(sparqlPanel);
                checkCurrentGraphPanel = CurrentGraphPanelInfo.SPARQL;
                outputTextArea.append("Search Result panel to SPARQL panel\n");            
            }else{
            }
        }else{
        }
    }
    //cg, st, sp 그래프 패널의 공통 레이아웃
    private void setGraphViewPanelLayout(ParallelGroup graphPanelHorizontalGroup, SequentialGroup graphPanelVerticalGroup){
        graphViewPanelLayout.setHorizontalGroup(
            graphViewPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addGroup(graphPanelHorizontalGroup)
        );        
        graphViewPanelLayout.setVerticalGroup(
            graphViewPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addGroup(graphViewPanelLayout.createSequentialGroup()
                    .addGroup(graphPanelVerticalGroup))
        );
    }
    //sparql패널에서 라디오버튼과sparql스크롤패널의 레이아웃
    private void setSPARQLGroupPanelLayout(GroupLayout sparqlGroupPaneLayout, JScrollPane sparqlScrollPane, JRadioButton sparqlRadioButton){
        sparqlGroupPaneLayout.setHorizontalGroup(
            sparqlGroupPaneLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addGroup(sparqlGroupPaneLayout.createSequentialGroup()
                .addComponent(sparqlRadioButton)
                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(sparqlScrollPane))
        );
        sparqlGroupPaneLayout.setVerticalGroup(
            sparqlGroupPaneLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addGroup(sparqlGroupPaneLayout.createSequentialGroup()
                .addGroup(sparqlGroupPaneLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
                    .addComponent(sparqlRadioButton)
                    .addComponent(sparqlScrollPane, GroupLayout.PREFERRED_SIZE, 100, GroupLayout.PREFERRED_SIZE))
                .addGap(0, 0, Short.MAX_VALUE))
        );
    }
/*
    private void setEachGraphViewPanelLayout(GroupLayout eachLayout) {
        eachLayout.setHorizontalGroup(
            eachLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addGap(0, 0, Short.MAX_VALUE)
        );
        eachLayout.setVerticalGroup(
            eachLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addGap(0, 200, Short.MAX_VALUE)
        );
    }
*/
    //cg, st 그래프패널에서 각각의 그래프그룹(아이디와 그래프)의 레이아웃
    private void setEachGraphViewPanelLayout(GroupLayout eachLayout, JLabel graphID, JPanel graphGroupPanel) {
        eachLayout.setHorizontalGroup(
            eachLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addGroup(eachLayout.createSequentialGroup()
                .addComponent(graphID, GroupLayout.PREFERRED_SIZE, 150, GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(graphGroupPanel))
        );
        eachLayout.setVerticalGroup(
            eachLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addGroup(eachLayout.createSequentialGroup()
                .addGroup(eachLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
                    .addComponent(graphID, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                    .addComponent(graphGroupPanel, GroupLayout.PREFERRED_SIZE, 350, GroupLayout.PREFERRED_SIZE))
                .addGap(0, 0, Short.MAX_VALUE))
        );
    }

    //sp 그래프패널에서 각각의 그래프그룹(아이디, 스코어, 그래프)의 레이아웃
    private void setEachGraphViewPanelLayout(GroupLayout eachLayout, JLabel graphID, JLabel graphScore, JPanel graphGroupPanel) {
        eachLayout.setHorizontalGroup(
            eachLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addGroup(eachLayout.createSequentialGroup()
                .addGroup(eachLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false)
                    .addComponent(graphID, GroupLayout.DEFAULT_SIZE, 150, Short.MAX_VALUE)
                    .addComponent(graphScore, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(graphGroupPanel))
        );
        eachLayout.setVerticalGroup(
            eachLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addGroup(eachLayout.createSequentialGroup()
                .addGroup(eachLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
                    .addComponent(graphGroupPanel, GroupLayout.PREFERRED_SIZE, 350, GroupLayout.PREFERRED_SIZE)
                    .addGroup(eachLayout.createSequentialGroup()
                        .addComponent(graphID, GroupLayout.PREFERRED_SIZE, 20, GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(graphScore, GroupLayout.PREFERRED_SIZE, 20, GroupLayout.PREFERRED_SIZE)))
                .addGap(0, 0, Short.MAX_VALUE))
        );
    }

    private void getGraphPanel() {
        graphPanel.repaint();
        GroupLayout graphPanelLayout = new GroupLayout(graphPanel);
        graphPanel.setLayout(graphPanelLayout);
        graphPanelLayout.setHorizontalGroup(
            graphPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addComponent(buttonPanel, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addComponent(graphViewScrollPane)
        );
        graphPanelLayout.setVerticalGroup(
            graphPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addGroup(graphPanelLayout.createSequentialGroup()
                .addComponent(graphViewScrollPane)
                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(buttonPanel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
        );
    }
    
    
    public static void main(String args[]) {
        try {
            for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (Exception ex) {
            Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        final JFrame frame = new MainFrame();
        frame.setVisible(true);
        frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
        WindowListener l = new WindowAdapter(){
            public void windowClosing(WindowEvent e){
                int confirm = JOptionPane.showOptionDialog(frame, "Really Exit?", "Exit Confirmation", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, null, null);
                if(confirm == 0){
                    frame.dispose();
                    System.exit(0);
                }
            }
        };
        frame.addWindowListener(l);
    }
}
